/**
	************************************************************
	************************************************************
	************************************************************
	*	文件名： 	main.c
	*
	*	作者： 		张继瑞
	*
	*	日期： 		2017-05-08
	*
	*	版本： 		V1.0
	*
	*	说明： 		接入onenet，上传数据和命令控制
	*
	*	修改记录：	
	************************************************************
	************************************************************
	************************************************************
**/

//单片机头文件
#include "stm32f10x.h"

//网络协议层
#include "onenet.h"

//网络设备
#include "esp8266.h"

//硬件驱动
#include "delay.h"
#include "usart.h"
#include "Key.h"
#include "dht11.h"
#include "LDR.h"
#include "mq7.h"
#include "PM25.h"
//#include "i2c.h"
#include "LED.h"
#include "beep.h"
#include "sht20.h"
#include "oled.h"
//C库
#include <string.h>


#define ESP8266_ONENET_INFO		"AT+CIPSTART=\"TCP\",\"mqtts.heclouds.com\",1883\r\n"

void Hardware_Init(void);
void Display1_Init(void);
void Display2_Init(void);
void Refresh1_Data(void);
void Refresh2_Data(void);
u8 temp,humi;
u16 light,pm;
float ppm = 0.0f;
typedef enum {
    DISPLAY_NONE = 0,   // 无显示
    DISPLAY_SCREEN1,    // 界面1：温湿度、台灯状态
    DISPLAY_SCREEN2     // 界面2：光照、CO浓度、粉尘
} DisplayScreen;

volatile DisplayScreen CurrentScreen = DISPLAY_NONE; // 当前显示界面
 uint8_t DisFlag = 0; 
extern uint8_t Key1 ,Key2;
	 


/*
************************************************************
*	函数名称：	Hardware_Init
*
*	函数功能：	硬件初始化
*
*	入口参数：	无
*
*	返回参数：	无
*
*	说明：		初始化单片机功能以及外接设备
************************************************************
*/
void Hardware_Init(void)
{
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//中断控制器分组设置

	Delay_Init();									//延时函数初始化
//	
	Usart1_Init(115200);							//串口1，打印信息用
	
	Usart2_Init(115200);							//串口2，驱动ESP8266用
//	
//	IIC_Init();			//软件IIC初始化
	
	
	PM25_Init();//粉尘传感器初始化
	
	MQ7_Init();//CO初始化
	
	LDR_Init();//光敏传感器初始化
	
	DHT11_Init();//温湿度传感器初始化
	
	Key_Init();//按键初始化&&中断配置
	
	LED_Init();//LED初始化
	
	Beep_Init();//蜂鸣器初始化
	
	OLED_Init();//OLED初始化

	//等待硬件初始化完成
	//等待温湿度初始化完成
	while(DHT11_Init())
	{
//		UsartPrintf(USART_DEBUG,"DHT11 Error \r\n");
			OLED_ShowString(0,0,"DHT11 Error",16);
		DelayMs(1000);
	}
	
//	UsartPrintf(USART_DEBUG, " Hardware init OK\r\n");
		OLED_Clear();
		OLED_ShowString(0,0,"Hardware init OK",16);
		DelayMs(1000);
	OLED_Clear();
	
}

/*
************************************************************
*	函数名称：	main
*
*	函数功能：	
*
*	入口参数：	无
*
*	返回参数：	0
*
*	说明：		
************************************************************
*/

int main(void)
{
//	
	
	unsigned short timeCount = 0;	//发送间隔变量
	
	unsigned char *dataPtr = NULL;
//	
	Hardware_Init();				//初始化外围硬件
//	
	ESP8266_Init();					//初始化ESP8266
//	
//	OneNET_RegisterDevice();
//	
	OLED_Clear();
	//打印初始化信息
//	UsartPrintf(USART_DEBUG, "Connect MQTTs Server...\r\n");
	OLED_ShowString(0,0," Connect MQTTs Server...",16);
	while(ESP8266_SendCmd(ESP8266_ONENET_INFO, "CONNECT"))
		DelayXms(500);
	OLED_ShowString(0,4," Connect MQTT Server Success...",16);
		DelayXms(500);
	OLED_Clear();
	OLED_ShowString(0,3," Device login...",16);
	//等待onenet平台连接
	while(OneNet_DevLink())	
	{
		ESP8266_SendCmd(ESP8266_ONENET_INFO, "CONNECT");
		DelayXms(500);
	}		//接入OneNET
		DelayXms(500);
	
	OneNET_Subscribe();
	OLED_Clear();
	CurrentScreen = DISPLAY_NONE;
//检测按键输入显示不同信息
	while(1)
	{
	

		if(Key1 == 1)
		{
		
			  Key1 = 0;
            OLED_Clear();
            CurrentScreen = DISPLAY_SCREEN1;
						Display1_Init();
					
	}
		if(Key2 == 1)
		{
		
						Key2 = 0;
            OLED_Clear();
            CurrentScreen = DISPLAY_SCREEN2;
						Display2_Init();
		}
		if(++timeCount >= 100)									//发送间隔1s
		{

			Get_PM25_Average_Data(&pm);
			MQ7_GetData_PPM(&ppm);
			DHT11_Read_Data(&temp,&humi);
			LDR_LuxData(&light);
			UsartPrintf(USART_DEBUG, "OneNet_SendData\r\n");
			OneNet_SendData();									//发送数据
			
			timeCount = 0;
			ESP8266_Clear();
		}
		
		
		
		dataPtr = ESP8266_GetIPD(0);
		if(dataPtr != NULL)
			OneNet_RevPro(dataPtr);
		
		  // 数据显示刷新
        switch(CurrentScreen)
        {
            case DISPLAY_SCREEN1:
                Refresh1_Data();
                break;
                
            case DISPLAY_SCREEN2:
                Refresh2_Data();
                break;
                
            default:
                // 无显示状态
                break;
        }
		
		//CO&&PM25超标检测
			if(ppm>CO_MAX){
		Beep_Set(BEEP_OFF);
		}
		else
		{
		Beep_Set(BEEP_ON);
		}
		
//			if(pm>PM25_MAX){
//		Beep_Set(BEEP_OFF);
//		}
//		else
//		{
//		Beep_Set(BEEP_ON);
//		}
		DelayXms(20);
	
	}

}

//静态打印函数1，2
void Display1_Init(void)
{
	
	
	OLED_ShowCHinese(0,0,1);//温    
	OLED_ShowCHinese(18,0,2);//度   
	OLED_ShowCHinese(36,0,0);//：   
	OLED_ShowCHinese(72,0,3);//℃  

	                                
	OLED_ShowCHinese(0,3,4);//湿    
	OLED_ShowCHinese(18,3,5);//度   
	OLED_ShowCHinese(36,3,0);//：   
	OLED_ShowString(72,3,"%",16);//%
	
	                                
	OLED_ShowCHinese(0,6,6);//台    
	OLED_ShowCHinese(18,6,7);//灯   
	OLED_ShowCHinese(36,6,0);//：   
}

void Display2_Init(void)
{

	
	OLED_ShowCHinese(0,0,10);//光  
	OLED_ShowCHinese(18,0,11);//强
	OLED_ShowCHinese(36,0,0);//：
	OLED_ShowString(80,0,"Lux",16);//Lux
	
//	OLED_ShowCHinese(0,3,12);//C
//	OLED_ShowCHinese(18,3,13);//O
	OLED_ShowString(0,3,"C",16);
	OLED_ShowString(18,3,"O",16);
	OLED_ShowCHinese(36,3,0);//：
	OLED_ShowString(80,3,"ppm",16);//ppm
	
	OLED_ShowCHinese(0,6,12);//粉
	OLED_ShowCHinese(18,6,13);//尘
	OLED_ShowCHinese(36,6,0);//：
	OLED_ShowString(80,6,"ug/m3",16);//ug/m³
	

}
//数据刷新显示1，2
void Refresh1_Data(void)
{
		char buf1[3];
		sprintf(buf1,"%2d",temp);
		OLED_ShowString(54,0,buf1,16); 
	
		sprintf(buf1,"%2d",humi);	
		OLED_ShowString(54,3,buf1,16);  
	
		if(LED_info.LED_Status)
		OLED_ShowCHinese(54,6,8);//亮
		else
		OLED_ShowCHinese(54,6,9);//灭

}

void Refresh2_Data(void)
{
		char buf2[3];
	
		sprintf(buf2,"%2d",light);	
		OLED_ShowString(54,0,buf2,16);  
	
		sprintf(buf2,"%.1f",ppm);	
		OLED_ShowString(54,3,buf2,16);  
	
		sprintf(buf2,"%2d",pm);	
		OLED_ShowString(54,6,buf2,16);  
	
}
